package easier.app.x.task;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 任务队列,同时执行指定数量任务,执行完成后继续执行下一组任务
 * {@link #onAccept(Object)}执行任务的逻辑
 * {@link #loop()}任务执行完成后调用该方法继续执行后续任务
 * {@link #configLoopTime()}配置同时执行的任务数量
 *
 * @param <E> 任务数据
 */
public abstract class QueueAction< E > {

    /**
     * 待处理任务队列
     */
    private final List< E > mList = new ArrayList<>();

    /**
     * 记录是否正在进行任务队列
     */
    private final AtomicBoolean isLooping = new AtomicBoolean( false );

    public void add( E e ) {

        if ( e == null ) {
            return;
        }

        /* 保证添加的任务一定在队尾,即使里面有也已经移除添加到队尾 */
        mList.remove( e );
        mList.add( e );

        if ( isLooping.get() ) {
            return;
        }

        loop();
    }

    public void remove( E e ) {

        if ( e == null ) {
            return;
        }

        mList.remove( e );
    }

    /**
     * 循环处理任务
     */
    public final void loop() {

        isLooping.set( true );

        int i = 0;
        while ( i < configLoopTime() ) {
            if ( mList.size() > 0 ) {
                E e = mList.remove( 0 );
                try {
                    onAccept( e );
                } catch ( Throwable ex ) {
                    ex.printStackTrace();
                }
            } else {
                isLooping.set( false );
                return;
            }
            i++;
        }
    }

    /**
     * @param e 实际处理任务,任务处理完成,必须调用{@link #loop()}进行下一个任务
     */
    protected abstract void onAccept( E e );

    protected int configLoopTime() {

        return 1;
    }
}
